import plugin from '../../../lib/plugins/plugin.js'
import { Render } from '../components/index.js'
import { twentyfour } from '../model/index.js';

export class game24 extends plugin {
    constructor() {
        super({
            name: '[xingchen-plugin] 24点',
            dsc: '[xingchen-plugin] 24点',
            event: 'message',
            priority: 1,
            rule: [
                {
                    reg: '^#24$',
                    fnc: 'game24'
                },
                {
                    reg: /^(\(|\d).*(\+|\-|\*|\/).*(\d|\))|无解$/,
                    fnc: 'game24ing'
                },
                {
                    reg: '^#24结束$',
                    fnc: 'game24end'
                },
                {
                    reg: '^#?24(榜|排行|排行榜)$',
                    fnc: 'game24rank'
                }
            ]
        })
    }

    async game24(e) {
        if (twentyfour.Gamestate == 1) {
            let arr = twentyfour.arr
            let text = `当前已有正在进行的24点游戏，请先完成当前游戏。\n请根据数组：[${arr[0]}, ${arr[1]}, ${arr[2]}, ${arr[3]}]\n输入表达式使其结果为 24。（若无解，请输入“无解”）`
            return await e.reply(text, true)
        } else {
            twentyfour.Gamestate = 1
            let arr = []
            for (let i = 0; i < 4; i++) {
                arr.push(Math.floor(Math.random() * (13 - 1)) + 1)
            }
            let text = `请根据数组：[${arr[0]}, ${arr[1]}, ${arr[2]}, ${arr[3]}]\n输入表达式使其结果为 24。（若无解，请输入“无解”）`
            const result = equalTo24(arr)
            twentyfour.answer = result
            twentyfour.arr = arr
            console.log(result[0])
            return await e.reply(text, true)
        }
    }

    async game24ing(e) {
        let data = JSON.parse(await redis.get(`Yunzai:xingchen-plugin:group${e.group_id}_game`)) || {}
        if (!data[e.user_id]) {
            data[e.user_id] = { name: e.sender.card, game24: 0, wordle: 0 };
        }
        if (twentyfour.Gamestate == 1) {
            let msg = e.msg
            msg = msg.replace(/(\d|\d\))(\()/g, '$1*$2');
            msg = msg.replace(/(\d\))(\d)/g, '$1*$2');
            let result
            if (msg !="无解"){
                result = eval(msg);
            }
            let bh = []
            for (let i = 0; i <4; i++) {
                let reg = msg.indexOf(twentyfour.arr[i])
                bh.push(reg)
            }
            console.log(bh)
            let gameanswer = twentyfour.answer.indexOf(msg)
            if (result == 24 && !bh.includes(-1)) {
                data[e.user_id].game24 = data[e.user_id].game24 + 2
                twentyfour.Gamestate = 0
                await redis.set(`Yunzai:xingchen-plugin:group${e.group_id}_game`, JSON.stringify(data))
                return await e.reply('答案正确！\n积分+2', true)
            }else if (gameanswer == -1) {
                data[e.user_id].game24 = data[e.user_id].game24 - 1
                twentyfour.Gamestate = 0
                await redis.set(`Yunzai:xingchen-plugin:group${e.group_id}_game`, JSON.stringify(data))
                let text = `回答错误：该组合存在解。\n其中一组解为:${twentyfour.answer[0]}\n积分-1`
                return await e.reply(text, true)
            } 

        }
    }

    async game24end(e) {
        if (twentyfour.Gamestate == 1) {
            twentyfour.Gamestate = 0
            let text = `游戏结束！\n其中一组解为:${twentyfour.gs[0]}`
            return await e.reply(text, true)
        }
        if (twentyfour.Gamestate == 0) {
            let text = `当前没有正在进行的24点游戏，请先开始游戏。`
            return await e.reply(text, true)
        }
    }

    async game24rank(e) {
        let groupdata = JSON.parse(await redis.get(`Yunzai:xingchen-plugin:group${e.group_id}_game`))
        if (!groupdata) {
            return await e.reply('当前群组没有进行过24点游戏', true)
        }
        const arr = Object.entries(groupdata);
        arr.sort((a, b) => b[1].game24 - a[1].game24);
        let title = `24点游排行榜`
        let ranklist = [];
        for (let i = 0; i < arr.length; i++) {
            if (arr[i][1].game24 == 0) {
                continue
            }
            let rank = {
                id: arr[i][0],
                name: arr[i][1].name,
                count: arr[i][1].game24,
            }
            ranklist.push(rank);
        }
        return await Render.render('game/rank', {
            ranklist,
            title,
            element: 'elem'
        }, { e, scale: 1.6 })
    }
}
var operator = [
    { name: "-", f: function (m, n) { return m - n } },
    { name: "+", f: function (m, n) { return m + n } },
    { name: "/", f: function (m, n) { return m / n } },
    { name: "*", f: function (m, n) { return m * n } }
]
function equalTo24(arr) {
    let s = arr.map(function (a) { return a.toString(); });
    var b = []
    for (var i in s)
        b[1 << i] = parseInt(s[i])
    var k = 0
    var result = {}
    var answer = []
    var fork = function (s) {
        s = s.replace("%", operator[f1].name).replace("%", operator[f2].name).replace("%", operator[f3].name)
        s = s.replace("N", b[i1]).replace("N", b[i2]).replace("N", b[i3]).replace("N", b[i4])
        if (result[s]) return
        result[s] = 1
        answer.push(s)
        return ++k >= 9999
    }
    for (var i1 = 1; i1 <= 8; i1 <<= 1)
        for (var i2 = 1; i2 <= 8; i2 <<= 1)
            for (var i3 = 1; i3 <= 8; i3 <<= 1)
                for (var i4 = 1; i4 <= 8; i4 <<= 1) {
                    if ((i1 | i2 | i3 | i4) != 0xf) continue;
                    for (var f1 = 0; f1 <= 3; f1++)
                        for (var f2 = 0; f2 <= 3; f2++)
                            for (var f3 = 0; f3 <= 3; f3++) {
                                var of1 = operator[f1], of2 = operator[f2], of3 = operator[f3];
                                // ((1,2)3)4
                                var m = of3.f(of2.f(of1.f(b[i1], b[i2]), b[i3]), b[i4]);
                                if (Math.abs(m - 24) < 1e-5)
                                    if (fork("((N%N)%N)%N")) return false
                                // 1((2,3)4)
                                m = of1.f(b[i1], of3.f(of2.f(b[i2], b[i3]), b[i4]));
                                if (Math.abs(m - 24) < 1e-5)
                                    if (fork("N%((N%N)%N)")) return false
                                //  (1(2,3))4
                                m = of3.f(of1.f(b[i1], of2.f(b[i2], b[i3])), b[i4]);
                                if (Math.abs(m - 24) < 1e-5)
                                    if (fork("(N%(N%N))%N")) return false
                                //1(2(3,4))
                                m = of1.f(b[i1], of2.f(b[i2], of3.f(b[i3], b[i4])));
                                if (Math.abs(m - 24) < 1e-5)
                                    if (fork("N%(N%(N%N))")) return false
                                //(1,2)(3,4)
                                m = of2.f(of1.f(b[i1], b[i2]), of3.f(b[i3], b[i4]));
                                if (Math.abs(m - 24) < 1e-5)
                                    if (fork("(N%N)%(N%N)")) return false
                            }
                }
    if (k == 0 && answer.length == 0) {
        answer = "无解"
    } return answer
}